package com.c611.smartclassroom.ali;

import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.iot.model.v20180120.QueryDeviceDesiredPropertyRequest;
import com.aliyuncs.iot.model.v20180120.QueryDeviceDesiredPropertyResponse;
import com.c611.smartclassroom.ali.lot.IotClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("/ali")
public class ali {
    private static DefaultAcsClient client;

    /**
     * 初始化客户端
     *  用户的 ak
     *  用户的 Secret
     */
    static {
        client = IotClient.getClient();
    }
//    private static DefaultAcsClient client = getClient();


    /**
     * 获取当前设备运行状态
     * @param iotId 或者 productKey与deviceName
     * @return
     * @throws ClientException
     */
    @RequestMapping("/GetDeviceStatus")
    public String GetDeviceStatus(String iotId, String productKey, String deviceName) throws ClientException {

        CommonRequest request = new CommonRequest();
        request.setMethod(MethodType.POST);
        request.setDomain("iot.cn-shanghai.aliyuncs.com");
        request.setVersion("2018-01-20");
        request.setAction("GetDeviceStatus");
        request.putQueryParameter("RegionId", "cn-shanghai");
        if (iotId != null) {
            request.putQueryParameter("IotId", iotId);
        } else {
            request.putQueryParameter("ProductKey", productKey);
            request.putQueryParameter("DeviceName", deviceName);
        }
        CommonResponse response = client.getCommonResponse(request);
        return response.getData();
    }



    /**
     *  设置设备属性值
     * @param iotId 或者 productKey与deviceName
     * @param identifier 属性名
     * @param value 属性值
     * @return
     * @throws ClientException
     */
    @RequestMapping("/SetDeviceProperty")
    public String SetDeviceProperty(String iotId, String productKey, String deviceName, String identifier, String value) throws ClientException {
        CommonRequest request = new CommonRequest();
        request.setMethod(MethodType.POST);
        request.setDomain("iot.cn-shanghai.aliyuncs.com");
        request.setVersion("2018-01-20");
        request.setAction("SetDeviceProperty");
        request.putQueryParameter("RegionId", "cn-shanghai");
        request.putQueryParameter("Items", "{ \""+ identifier + "\"" + ":" +  value + "}");
        if (iotId != null) {
            request.putQueryParameter("IotId", iotId);
        } else {
            request.putQueryParameter("ProductKey", productKey);
            request.putQueryParameter("DeviceName", deviceName);
        }
        CommonResponse response = client.getCommonResponse(request);
        return response.getData();
    }

    /**
     *  设置设备属性值
     * @param iotId
     * @param items
     * @param
     * @return
     * @throws ClientException
     */
    @RequestMapping("/SetDeviceProperties")
    public String SetDeviceProperties(String iotId,String items) throws ClientException {
        CommonRequest request = new CommonRequest();
        request.setMethod(MethodType.POST);
        request.setDomain("iot.cn-shanghai.aliyuncs.com");
        request.setVersion("2018-01-20");
        request.setAction("SetDeviceProperty");
        request.putQueryParameter("RegionId", "cn-shanghai");
        request.putQueryParameter("Items", items);
            if (iotId != null) {
            request.putQueryParameter("IotId", iotId);
        } /*else {
            request.putQueryParameter("ProductKey", productKey);
            request.putQueryParameter("DeviceName", deviceName);
        }*/
        CommonResponse response = client.getCommonResponse(request);
        return response.getData();
    }

    /**
     *  设置设备属性值(根据iotid)
     * @param iotId
     * @param identifier
     * @param value
     * @return
     * @throws ClientException
     */
    @RequestMapping("/SetDevicePropertyByIotId")
    public String SetDevicePropertyByIotId(String iotId,String identifier, String value) throws ClientException {
        CommonRequest request = new CommonRequest();
        request.setMethod(MethodType.POST);
        request.setDomain("iot.cn-shanghai.aliyuncs.com");
        request.setVersion("2018-01-20");
        request.setAction("SetDeviceProperty");
        request.putQueryParameter("RegionId", "cn-shanghai");
        request.putQueryParameter("Items", "{ \""+ identifier + "\"" + ":" +  value + "}");
        if (iotId != null) {
            request.putQueryParameter("IotId", iotId);
        } /*else {
            request.putQueryParameter("ProductKey", productKey);
            request.putQueryParameter("DeviceName", deviceName);
        }*/
        CommonResponse response = client.getCommonResponse(request);
        return response.getData();
    }


    /**
     *  获取设备信息（可获得多个设备）  //这里多次调用
     * @param productKey
     * @param deviceName
     * @return
     * @throws ClientException
     */
    @RequestMapping("/BatchQueryDeviceDetail")
    public String BatchQueryDeviceDetail(String productKey, String deviceName) throws ClientException {
        CommonRequest request = new CommonRequest();
        request.setMethod(MethodType.POST);
        request.setDomain("iot.cn-shanghai.aliyuncs.com");
        request.setVersion("2018-01-20");
        request.setAction("BatchQueryDeviceDetail");
        request.putQueryParameter("RegionId", "cn-shanghai");
        request.putQueryParameter("DeviceName.1", deviceName);

        request.putQueryParameter("ProductKey", productKey);
        CommonResponse response = client.getCommonResponse(request);
        return response.getData();
    }


    /**
     *  获取设备当前各属性值
     * @param iotId 或者  productKey 和 deviceName
     * @return json格式各设备的属性值
     * @throws ClientException
     */
    @RequestMapping("/QueryDevicePropertyStatus")
    public String QueryDevicePropertyStatus(String iotId, String productKey, String deviceName) throws ClientException {

        CommonRequest request = new CommonRequest();
        request.setMethod(MethodType.POST);
        request.setVersion("2018-01-20");
        request.setDomain("iot.cn-shanghai.aliyuncs.com");
        request.setAction("QueryDevicePropertyStatus");
        request.putQueryParameter("RegionId", "cn-shanghai");
        if (iotId != null) {
            request.putQueryParameter("IotId", iotId);
        } else {
            request.putQueryParameter("ProductKey", productKey);
            request.putQueryParameter("DeviceName", deviceName);
        }
        CommonResponse response = client.getCommonResponse(request);
//        String json = JSON.toJSONString(response.getData());
        return response.getData();
    }

    /**
     * 实时获取设备属性值 （重复获取）
     * @param iotId
     * @param productKey
     * @param deviceName
     * @return
     * @throws ClientException
     */
    @RequestMapping("/QueryDeviceStatus")
    public String QueryDeviceStatus(String iotId, String productKey, String deviceName) throws ClientException {
        while(true){
            CommonRequest request = new CommonRequest();
            request.setMethod(MethodType.POST);
            request.setVersion("2018-01-20");
            request.setDomain("iot.cn-shanghai.aliyuncs.com");
            request.setAction("QueryDevicePropertyStatus");
            request.putQueryParameter("RegionId", "cn-shanghai");
            if (iotId != null) {
                request.putQueryParameter("IotId", iotId);
            } else {
                request.putQueryParameter("ProductKey", productKey);
                request.putQueryParameter("DeviceName", deviceName);
            }
            CommonResponse response = client.getCommonResponse(request);
            System.out.println(response.getData());
            return response.getData();
        }
    }



    /**
     * 查看当前产品信息
     * @param productKey
     * @return
     * @throws ClientException
     */
    @RequestMapping("/QueryProduct")
    public String QueryProduct(String productKey) throws ClientException {
        CommonRequest request = new CommonRequest();
        request.setMethod(MethodType.POST);
        request.setDomain("iot.cn-shanghai.aliyuncs.com");
        request.setVersion("2018-01-20");
        request.setAction("QueryProduct");
        request.putQueryParameter("RegionId", "cn-shanghai");
        request.putQueryParameter("ProductKey", productKey);
        CommonResponse response = client.getCommonResponse(request);
        return response.getData();
    }


    /**
     * 查询设备期望属性值
     * @param iotId 或者 productKey与deviceName
     * @param identifier 属性名
     * @return
     * @throws ClientException
     */
    @RequestMapping("/QueryDeviceDesiredProperty")
    // 待查询的属性identifier列表。如不指定则查询所有属性（只读属性除外）的期望属性值。
    public List<QueryDeviceDesiredPropertyResponse.Data.DesiredPropertyInfo> QueryDeviceDesiredProperty(String iotId, String productKey, String deviceName, String identifier) throws ClientException {

        // 创建API请求并设置参数
        QueryDeviceDesiredPropertyRequest request = new QueryDeviceDesiredPropertyRequest();
        if (iotId == null){
            request.setProductKey(productKey);
            request.setDeviceName(deviceName);
        }else {
            request.setIotId(iotId);
        }

        // 待查询的属性identifier列表。如不指定则查询所有属性（只读属性除外）的期望属性值。
        if (identifier == null){
            request.setIdentifiers(Arrays.asList());
        } else {
            request.setIdentifiers(Arrays.asList(identifier));
        }

        // 发起请求并处理应答或异常
        QueryDeviceDesiredPropertyResponse response;

            response = client.getAcsResponse(request);

            QueryDeviceDesiredPropertyResponse.Data data = response.getData();

            return data.getList();

    }


    /**
     * 设置设备属性期望值
     * @param iotId 或者 productKey与deviceName，
     * @param identifier 期望属性名
     * @param value 期望属性值
     * @return
     * @throws ClientException
     */
    @RequestMapping("/SetDeviceDesiredProperty")
    public String SetDeviceDesiredProperty(String iotId, String productKey, String deviceName, String identifier, String value) throws ClientException {
        CommonRequest request = new CommonRequest();
        request.setMethod(MethodType.POST);
        request.setDomain("iot.cn-shanghai.aliyuncs.com");
        request.setVersion("2018-01-20");
        request.setAction("SetDeviceDesiredProperty");
        request.putQueryParameter("RegionId", "cn-hangzhou");
        request.putQueryParameter("Items", "{ \""+ identifier + "\"" + ":" +  value + "}");
        request.putQueryParameter("RegionId", "cn-shanghai");
        if (iotId == null) {
            request.putQueryParameter("ProductKey", productKey);
            request.putQueryParameter("DeviceName", deviceName);
        } else {
            request.putQueryParameter("IotId", iotId);
        }
        CommonResponse response = client.getCommonResponse(request);

        return response.getData();

    }




    public static DefaultAcsClient getClient() {
        return client;
    }
}

/*


    private final static Logger logger = LoggerFactory.getLogger(ali.class);
    private final static ExecutorService executorService = new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors(),
            Runtime.getRuntime().availableProcessors() * 2, 60, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(50000));

    @RequestMapping("/AmqpJavaClient")
    public String AmqpJavaClient() throws Exception {
        String accessKey = "LTAI4FoFPiDKCuwmX9Ym8Tfb";   //必填
        String accessSecret = "gJFIn4E1YlVfmPt9P6kwCyRxF9BpuW";  //必填
        String consumerGroupId = "d7zeSPuSKyN2GAIw2mow000100";  //必填 消费组id
        long timeStamp = System.currentTimeMillis();
        //签名方法：支持hmacmd5，hmacsha1和hmacsha256
        String signMethod = "hmacsha1";
        //控制台服务端订阅中消费组状态页客户端ID一栏将显示clientId参数。
        //建议使用机器UUID、MAC地址、IP等唯一标识等作为clientId。便于区分识别不同的客户端。
        String clientId = "421526357";  //必填

        //UserName组装方法，文档：AMQP客户端接入说明。
        String userName = clientId + "|authMode=aksign"
                + ",signMethod=" + signMethod
                + ",timestamp=" + timeStamp
                + ",authId=" + accessKey
                + ",consumerGroupId=" + consumerGroupId
                + "|";
        //password组装方法，文档：AMQP客户端接入说明。
        String signContent = "authId=" + accessKey + "&timestamp=" + timeStamp;
        String password = doSign(signContent,accessSecret, signMethod);
        //按照qpid-jms的规范，组装连接URL。     // ⬇   UID      ⬇
        String connectionUrl = "failover:(amqps://1679473134589533.iot-amqp.cn-shanghai.aliyuncs.com:5671?amqp.idleTimeout=80000)"
                + "?failover.reconnectDelay=30";

        Hashtable<String, String> hashtable = new Hashtable<>();
        hashtable.put("connectionfactory.SBCF",connectionUrl);
        hashtable.put("queue.QUEUE", "default");
        hashtable.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.qpid.jms.jndi.JmsInitialContextFactory");
        Context context = new InitialContext(hashtable);
        ConnectionFactory cf = (ConnectionFactory)context.lookup("SBCF");
        Destination queue = (Destination)context.lookup("QUEUE");
        // Create Connection
        Connection connection = cf.createConnection(userName, password);
        ((JmsConnection) connection).addConnectionListener(myJmsConnectionListener);
        // Create Session
        // Session.CLIENT_ACKNOWLEDGE: 收到消息后，需要手动调用message.acknowledge()
        // Session.AUTO_ACKNOWLEDGE: SDK自动ACK（推荐）
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        connection.start();
        // Create Receiver Link
        MessageConsumer consumer = session.createConsumer(queue);
        consumer.setMessageListener(messageListener);
        return null;
    }


    private static MessageListener messageListener = new MessageListener() {
        @Override
        public void onMessage(Message message) {
            try {
                //1.收到消息之后一定要ACK
                // 做法1：创建Session选择Session.AUTO_ACKNOWLEDGE，这里会自动ACK。

                // 做法2：创建Session选择Session.CLIENT_ACKNOWLEDGE，这里一定要调message.acknowledge()来ACK。
                // message.acknowledge();
                //2.建议异步处理收到的消息，确保onMessage函数里没有耗时逻辑。
                // 如果业务处理耗时过程过长阻塞住线程，可能会影响SDK收到消息后的正常回调。
                executorService.submit(() -> processMessage(message));
            } catch (Exception e) {
                logger.error("submit task occurs exception ", e);
            }
        }
    };


    */
/**
     * 在这里处理收到消息后的具体业务逻辑。
     *//*

     private static void processMessage(Message message) {
        try {
            byte[] body = message.getBody(byte[].class);
            String content = new String(body);
            String topic = message.getStringProperty("topic");
            String messageId = message.getStringProperty("messageId");



            logger.info("receive message"
                    + ", topic = " + topic
                    + ", messageId = " + messageId
                    + ", content = " + content);
        } catch (Exception e) {
            logger.error("processMessage occurs error ", e);
        }
    }
    private static JmsConnectionListener myJmsConnectionListener = new JmsConnectionListener() {
        */
/**
         * 连接成功建立
         *//*

        @Override
        public void onConnectionEstablished(URI remoteURI) {
            logger.info("onConnectionEstablished, remoteUri:{}", remoteURI);
        }

        */
/**
         * 尝试过最大重试次数之后，最终连接失败。
         *//*

        @Override
        public void onConnectionFailure(Throwable error) {
            logger.error("onConnectionFailure, {}", error.getMessage());
        }

        */
/**
         * 连接中断。
         *//*

        @Override
        public void onConnectionInterrupted(URI remoteURI) {
            logger.info("onConnectionInterrupted, remoteUri:{}", remoteURI);
        }

        */
/**
         * 连接中断后又自动重连上。
         *//*

        @Override
        public void onConnectionRestored(URI remoteURI) {
            logger.info("onConnectionRestored, remoteUri:{}", remoteURI);
        }

        @Override
        public void onInboundMessage(JmsInboundMessageDispatch envelope) {}

        @Override
        public void onSessionClosed(Session session, Throwable cause) {}

        @Override
        public void onConsumerClosed(MessageConsumer consumer, Throwable cause) {}

        @Override
        public void onProducerClosed(MessageProducer producer, Throwable cause) {}
    };

    */
/**
     * password签名计算方法，参见文档：AMQP客户端接入说明。
     *//*

    private static String doSign(String toSignString, String secret, String signMethod) throws Exception {
        SecretKeySpec signingKey = new SecretKeySpec(secret.getBytes(), signMethod);
        Mac mac = Mac.getInstance(signMethod);
        mac.init(signingKey);
        byte[] rawHmac = mac.doFinal(toSignString.getBytes());
        return Base64.encodeBase64String(rawHmac);
    }

}
*/
